﻿using System;

public class Sphere:Primitive
{
    public Vector3 centre;
    public float R;
    public Sphere(Vector3 centre, float R)
    {
        this.centre = centre;
        this.R = R;
        this.material = new Material();
    }
	public Sphere(Vector3 centre, float R, LightIntensity ambient, LightIntensity diffuse, LightIntensity specular)
	{
        this.centre = centre;
        this.R = R;
        this.material = new Material(ambient, diffuse, specular);
	}
    public override string ToString()
    {
        return "sphere{c" + centre + ", R=" + R + "}";
    }
    public override Vector3 getNormal(Vector3 point)
    {
        Vector3 normal = point - this.centre;
        normal.normalize();
        return normal;
    }
    public override Vector3 getCentre()
    {
        return centre;
    }
    public override float getWidth()
    {
        return R;
    }
    public override bool intersect(Ray r)
    {
        Vector3 v = r.origin - this.centre;
        float a = r.direction.dot(r.direction);
        float b = 2*(r.direction.dot(v));
        float c = v.dot(v) - (this.R * this.R);
        float det = (b * b) - 4*a*c;
        if (det >= 0)
        {
            det = (float)Math.Sqrt(det);
            if (det != 0)
            {
                float t1 = (-b - det) / (2 * a);
                float t2 = (-b + det) / (2 * a);
                //if (t1 >= 0 && t2 >= 0 )
                if (t1 > Sphere.plusZero && t2 > Sphere.plusZero)
                {
                    if (t1 > t2)
                    {
                        if (t2 > Sphere.plusZero)
                        {
                            if (r.distance > t2 || r.distance == 0)
                            {
                                r.distance = t2;
                                r.destination = new Vector3(r.origin + r.distance * r.direction);
                                //Console.WriteLine("Promien przecina sferę w punkcie i=" + r.destination);
                                return true;
                            }
                            else
                            {
                                //Console.WriteLine("Promien nie przecina sfery");
                                return false;
                            }
                        }
                        else
                        {
                            if (r.distance > t1 || r.distance == 0)
                            {
                                r.distance = t1;
                                r.destination = new Vector3(r.origin + r.distance * r.direction);
                                //Console.WriteLine("Promien przecina sferę w punkcie i=" + r.destination);
                                return true;
                            }
                            else
                            {
                                //Console.WriteLine("Promien nie przecina sfery");
                                return false;
                            }
                        }
                    }
                    else
                    {
                        if (t1 > Sphere.plusZero)
                        {
                            if (r.distance > t1 || r.distance == 0)
                            {
                                r.distance = t1;
                                r.destination = new Vector3(r.origin + r.distance * r.direction);
                                //Console.WriteLine("Promien przecina sferę w punkcie i=" + r.destination);
                                return true;
                            }
                            else
                            {
                                //Console.WriteLine("Promien nie przecina sfery");
                                return false;
                            }
                        }
                        else
                        {
                            if (r.distance > t2 || r.distance == 0)
                            {
                                r.distance = t2;
                                r.destination = new Vector3(r.origin + r.distance * r.direction);
                                //Console.WriteLine("Promien przecina sferę w punkcie i=" + r.destination);
                                return true;
                            }
                            else
                            {
                                //Console.WriteLine("Promien nie przecina sfery");
                                return false;
                            }
                        }
                    }
                }
                else
                {
                    //Console.WriteLine("Promien nie przecina sfery");
                    return false;
                }
            }
            else
            {
                float t = (-b) / (2 * a);
                if (t > Sphere.plusZero)
                {
                    if (r.distance > t || r.distance == 0)
                    {
                        r.distance = t;
                        r.destination = new Vector3(r.origin + r.distance * r.direction);
                        //Console.WriteLine("Promien jest styczny do sfery w punkcie i=" + r.destination);
                        return true;
                    }
                    else
                    {
                        //Console.WriteLine("Promien nie przecina sfery");
                        return false;
                    }
                    
                }
                else
                {
                    //Console.WriteLine("Promien nie przecina sfery");
                    return false;
                }
            }
        }
        else
        {
            //Console.WriteLine("Promien nie przecina sfery");
            return false;
        }
    }
}
